const { muser } = require('../models/muser');
const Joi = require('joi');
const validationMiddleware = require('../middleware/validate');
const response = require("../utils/response");
const router = require('koa-router')();

const { role } = require("../models/mrole");
const bcrypt = require('bcryptjs');
const { dealNotEmpty, dealNotEmptyArry, handleDatabaseError } = require("../utils/dberrordeal");
const { easyCopy } = require("../utils/utils");
const { sign, verify,signRefreshToken,verifyRefreshToken } = require('../utils/auth');
router.use(verify);

const rulesSchema = {
    '/adduser': Joi.object({
        username: dealNotEmpty('用户名'),
    }),
    '/putuser': Joi.object({
        username: dealNotEmpty('用户名'),
    }),
    '/deluser': Joi.object({
        id: dealNotEmpty('用户ID')
    }),
    '/getuser': Joi.object({
        id: dealNotEmpty('用户ID')
    })
};

router.post('/adduser', validationMiddleware(rulesSchema), async (ctx, next) => {
    let data = ctx.request.body;

    let isExist = await muser.findOne({ username: data.username });

    if (isExist) {
        return response.error(ctx, { message: '用户名已存在' });
    } else {
        data.password = await bcrypt.hash('111', await bcrypt.genSalt(10));
    }

    await muser.create(data).then(res => {
        response.success(ctx, { message: '注册成功' });
    }).catch(err => {
        handleDatabaseError(ctx, err, '用户名已存在');
    });
});

router.post('/putuser', validationMiddleware(rulesSchema), async (ctx, next) => {
    let data = ctx.request.body;
    let id = data._id || data.id

    if (data.o && data.n) {
        await muser.findOne({ _id: id }).then(async res => {
            if (!res) {
                return response.error(ctx, { message: '用户不存在' });
            }
            const isPasswordValid = await bcrypt.compare(data.o.toString(), res.password);
            if (!isPasswordValid) {
                return response.error(ctx, { message: '旧密码不正确' });
            }
            // 加密新密码
            const hashedPassword = await bcrypt.hash(data.n.toString(), await bcrypt.genSalt(10));
            data.password = hashedPassword
            await muser.findOneAndUpdate({ _id: id }, { $set: data }).then(res => {
                response.success(ctx, { message: '修改成功' });
            }).catch(err => {
                handleDatabaseError(ctx, err, '用户名已存在');
            });

        }).catch(err => {
            response.error(ctx, { message: '获取失败' });
        });
    } else {
        data.avatar = data.sex == 1 ? `${url}nan.png` : `${url}nv.png`
        await muser.findOneAndUpdate({ _id: id }, { $set: data }).then(res => {
            response.success(ctx, { message: '修改成功' });
        }).catch(err => {
            handleDatabaseError(ctx, err, '用户名已存在');
        });
    }



});

router.post('/resetuser', async (ctx, next) => {
    let data = ctx.request.body;
    let id = data.id

    if (!data.auth || data.auth != 'tuisa') {
        return response.error(ctx, { message: 'auth错误' });
    }

    const hashedPassword = await bcrypt.hash(data.password.toString(), await bcrypt.genSalt(10));
    if (hashedPassword) {
        data.password = hashedPassword
        await muser.findOneAndUpdate({ _id: id }, { $set: data }).then(res => {

            response.success(ctx, { message: '重置成功' });
        }).catch(err => {
            handleDatabaseError(ctx, err, '用户名已存在');
        });
    }




});

router.post('/getuser', validationMiddleware(rulesSchema), async (ctx, next) => {
    let data = ctx.request.body;
    await muser.findOne({ _id: data.id }).then(res => {
        response.success(ctx, { data: res });
    }).catch(err => {
        response.error(ctx, { message: '获取失败' });
    });
});

router.post('/deluser', validationMiddleware(rulesSchema), async (ctx, next) => {
    let data = ctx.request.body;
    await muser.findOneAndDelete({ _id: data.id }).then(res => {
        response.success(ctx, { data: res });
    }).catch(err => {
        response.error(ctx, { message: '删除失败' });
    });
});

router.get('/auth', async (ctx) => {
    response.success(ctx, {});
});

router.get('/getuserinfo', async (ctx, next) => {
    let id = ctx.userId

    const res = await muser.findOne({ _id: id }).populate({
        path: 'roles',
        select: 'name btnroles',
        populate: {
            path: 'roles',
            model: 'menu',
            select: 'name alias'
        }
    }).exec();
    if (res) {
        response.success(ctx, { data: res });
    } else {
        response.error(ctx, {});
    }
}
);
async function getRolesByIds(roleIds) {
    return new Promise(async (resolve, reject) => {
        try {
            const roles = await role.find({ _id: { $in: roleIds } }).populate('roles');
            if (roles.length === 0) {
                resolve([]);
            } else {
                resolve(roles.map(e => e.name));
            }
        } catch (err) {
            reject(err);
        }
    });
}

router.post('/refreshToken', async (ctx, next) => {
    const {refreshToken}  = ctx.request.body;



    if (!refreshToken) {
        return response.error(ctx, { message: '无刷新凭证，请重新登录', status: 401 });
    }
    try {


        const refreshRes = verifyRefreshToken(ctx,refreshToken);

        if (refreshRes) {
            const user = await muser.findOne({ _id: refreshRes.id  });
            let froles = await getRolesByIds(user.roles);
            let cres = easyCopy(user);
            cres.roles = froles;
            delete cres.password;
            const accessToken = sign({ id: refreshRes.id });
            const refreshToken = signRefreshToken({ id: refreshRes.id });
            response.success(ctx, {
                message: '登录成功', data: {
                    token:accessToken,
                    refreshToken,
                    userinfo:cres
                }
            });
        }
    }
    catch (error) {
        console.log(error, 'error')
        return response.error(ctx, { message: 'refreshtoken错误', status: 401 });
    }
});

router.post('/login', async (ctx, next) => {
    let data = ctx.request.body;
    const res = await muser.findOne({ username: data.username });
    if (!res) {
        return response.error(ctx, { message: '用户不存在' });
    } else {
        if (res.disabled) {
            response.error(ctx, { message: '该账户已被禁用' });
        }

        try {
            const isPasswordValid = await bcrypt.compare(data.password.toString(), res.password);
            if (!isPasswordValid) {
                return response.error(ctx, { message: '密码不正确' });
            }
        } catch (e) {
            console.log(e, 'eee')
        }


        const accessToken = sign({ id: res.id });
        const refreshToken = signRefreshToken({ id: res.id });


        let froles = await getRolesByIds(res.roles);
        let cres = easyCopy(res);
        cres.roles = froles;
        delete cres.password;
        response.success(ctx, {
            message: '登录成功', data: {
                userinfo: cres,
                token:accessToken,
                refreshToken
            }
        });
    }

});



router.post('/getorole', async (ctx, next) => {
    let id = ctx.request.body.id;
    const res = await role.findOne({ _id: id })

    if (res) {
        response.success(ctx, { message: '获权成功', data: res });
    } else {

        response.error(ctx, { message: '获权失败' });
    }
});




router.post('/getrole', async (ctx, next) => {
    let id = ctx.userId;
    const res = await muser.findOne({ _id: id }).populate({
        path: 'roles',
        select: 'name order disabled btnroles',
        populate: {
            path: 'roles',
            model: 'menu',
            select: 'name path disabled isMenu order parentId'
        }
    }).sort({ order: 1 }).exec();
    if (res) {
        response.success(ctx, { message: '获权成功', data: res.roles });
    } else {

        response.error(ctx, { message: '获权失败' });
    }
});

router.get('/userlist', async (ctx, next) => {
    const roles = await muser.find().populate('roles', 'name').exec();
    if (roles) {
        response.success(ctx, { data: roles.sort((a, b) => a.order - b.order) });
    } else {
        response.error(ctx, {});
    }
});

module.exports = router;
